﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using ProgNetComponents.Classes;
using System.ComponentModel.Design;

namespace ProgNetComponentsDx.Base.Classes
{
    [TypeConverter(typeof(ExpandableObjectConverter))]
    [ToolboxItem(false)]
    public abstract class BaseSettings : BaseCustomObject, IComponent
    {
        protected void SetFieldValue<T>(ref T oldValue, T newValue)
        {
            if (!oldValue.IsTheSame(newValue))
            {
                oldValue = newValue;
                OnSettingsChanged();
            }
        }

        protected object _Owner;
        [Browsable(false)]
        [ReadOnly(true)]
        public object Owner
        {
            get { return _Owner; }
        }
        
        protected IExtenderProvider _Provider;
        [Browsable(false)]
        public IExtenderProvider Provider
        {
            get { return _Provider; }
        }

        private BaseSettingsChangedEventArgs args = null;

        public BaseSettings(object target, IExtenderProvider provider)
        {
            this._Owner = target;
            this._Provider = provider;
        }

        protected bool isInitialized = true;

        [Browsable(false)]
        public event EventHandler<BaseSettingsChangedEventArgs> SettingsChanged;

        protected void OnSettingsChanged()
        {
            if (SettingsChanged != null && isInitialized)
            {
                if (args == null)
                    args = new BaseSettingsChangedEventArgs(this);
                SettingsChanged(_Owner, args);
            }
            //if (Provider is Component && Provider != null)
            //{
            //    IDesignerHost host = (Provider as Component).GetService<IDesignerHost>();
            //    if (host != null && !host.InTransaction)
            //    {
            //        host.CreateTransaction().Commit();
            //    }
            //}
        }

        public virtual void BeginSettings()
        {
            isInitialized = false;
        }

        public virtual void EndSettings()
        {
            isInitialized = true;
            OnSettingsChanged();
        }

        public override string ToString()
        {
            return GetType().Name;
        }

        #region IComponent Members

        event EventHandler IComponent.Disposed
        {
            add { throw new NotImplementedException(); }
            remove { throw new NotImplementedException(); }
        }

        ISite IComponent.Site
        {
            get
            {
                return (_Provider as IComponent).Site;
            }
            set
            {
                
            }
        }

        #endregion

        #region IDisposable Members

        void IDisposable.Dispose()
        {
            //throw new NotImplementedException();
        }

        #endregion

        public override PropertyDescriptorCollection GetProperties()
        {
            PropertyDescriptorCollection coll =  base.GetProperties();
            FilterDesignTime(coll);
            return coll;
        }

        public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
             PropertyDescriptorCollection coll = base.GetProperties(attributes);
             FilterDesignTime(coll);
             return coll;
        }
        private void FilterDesignTime(PropertyDescriptorCollection coll)
        {
            try
            {
                List<PropertyDescriptor> del = new List<PropertyDescriptor>();
                foreach (PropertyDescriptor p in coll)
                {
                    if (p.DesignTimeOnly)
                        del.Add(p);
                }
                foreach (PropertyDescriptor p in del)
                    coll.Remove(p);
            }
            catch { }
        }
        
    }

    public class BaseSettingsChangedEventArgs : EventArgs
    {
        private BaseSettings _Settings;

        public BaseSettings Settings
        {
            get { return _Settings; }
        }
        public BaseSettingsChangedEventArgs(BaseSettings s)
        {
            _Settings = s;
        }
    }

}
